using System;
using System.Collections.Generic;
using UnityEngine;

namespace UI.BankingPanel.Data
{
    /// <summary>
    /// 统计数据结构
    /// </summary>
    [Serializable]
    public class StatisticsData
    {
        [Header("统计数据")]
        public float revenueTotal;      // 下注总数（所有号码的总押注）
        public float eatCodeTotal;      // 吃码总数
        public float reportTotal;       // 上报总数
        public float odds;              // 赔率
        
        /// <summary>
        /// 构造函数
        /// </summary>
        public StatisticsData()
        {
            revenueTotal = 0f;
            eatCodeTotal = 0f;
            reportTotal = 0f;
            odds = 47f;
        }
        
        /// <summary>
        /// 更新统计数据
        /// </summary>
        /// <param name="totalBetAmount">下注总数</param>
        /// <param name="eatCode">吃码总数</param>
        /// <param name="report">上报总数</param>
        /// <param name="currentOdds">当前赔率</param>
        public void UpdateStatistics(float totalBetAmount, float eatCode, float report, float currentOdds)
        {
            revenueTotal = totalBetAmount;
            eatCodeTotal = eatCode;
            reportTotal = report;
            odds = currentOdds;
        }
    }

    /// <summary>
    /// 单个号码的押注数据
    /// </summary>
    [Serializable]
    public class NumberBetData
    {
        [Header("号码信息")]
        public int number;              // 号码
        
        [Header("押注数据")]
        public float totalBetAmount;    // 押注总数
        public float selfBetAmount;     // 自己吃码数
        public float reportAmount;      // 上报数
        
        [Header("风险计算")]
        public float riskValue;         // 风险值
        
        [Header("智能恢复")]
        public float originalEatCode;   // 被限制调整前的原始吃码（用于智能恢复）
        
        /// <summary>
        /// 构造函数
        /// </summary>
        public NumberBetData(int num)
        {
            number = num;
            totalBetAmount = 0f;
            selfBetAmount = 0f;
            reportAmount = 0f;
            riskValue = 0f;
            originalEatCode = 0f;
        }
        
        /// <summary>
        /// 更新上报数量 (总押注 - 自己吃码 = 上报数)
        /// </summary>
        public void UpdateReportAmount()
        {
            reportAmount = totalBetAmount - selfBetAmount;
            // 确保上报数量不为负数，并且是整数
            if (reportAmount < 0)
            {
                reportAmount = 0;
            }
            else
            {
                // 确保上报数量是整数
                reportAmount = Mathf.Floor(reportAmount);
            }
        }
        
        /// <summary>
        /// 计算风险值 - 表示如果该号码开奖时的净盈亏
        /// </summary>
        /// <param name="odds">赔率</param>
        /// <param name="allNumbersData">所有号码的数据（用于计算总收入）</param>
        public void CalculateRiskValue(float odds, List<NumberBetData> allNumbersData = null)
        {
            // 计算如果该号码开奖时的净盈亏
            // 净盈亏 = 所有号码的吃码总和 - 该号码的赔付
            
            float allNumbersEatCodeTotal = 0f; // 所有号码的吃码总和（我的总收入）
            
            if (allNumbersData != null)
            {
                // 计算所有号码的吃码总和
                foreach (var data in allNumbersData)
                {
                    allNumbersEatCodeTotal += data.selfBetAmount;
                }
            }
            
            // 该号码开奖时需要赔付的金额（只赔付我吃的部分）
            float payoutAmount = selfBetAmount * odds;
            
            // 计算风险值 = 所有号码吃码总和 - 该号码赔付
            riskValue = allNumbersEatCodeTotal - payoutAmount;
        }

        /// <summary>
        /// 根据字段类型获取对应的值
        /// </summary>
        /// <param name="fieldType">字段类型</param>
        /// <returns>字段值</returns>
        public float GetFieldValue(UI.BankingPanel.Components.BetDataFieldType fieldType)
        {
            switch (fieldType)
            {
                case UI.BankingPanel.Components.BetDataFieldType.TotalBet:
                    return totalBetAmount;
                case UI.BankingPanel.Components.BetDataFieldType.EatCode:
                    return selfBetAmount;
                case UI.BankingPanel.Components.BetDataFieldType.Report:
                    return reportAmount;
                default:
                    return 0f;
            }
        }
    }
    
    /// <summary>
    /// 庄家数据管理
    /// </summary>
    [Serializable]
    public class BankingData
    {
        [Header("基础设置")]
        public float averageBetAmount = 206f;   // 平均吃码数设置
        public float maxLossLimit = 4000f;      // 最大亏损限制
        public float odds = 47f;                // 赔率
        
        [Header("总体数据")]
        public float totalBetAmount;            // 下注总数
        public float totalSelfBetAmount;        // 自己吃码总数
        public float totalReportAmount;         // 总上报数
        
        [Header("号码数据")]
        public List<NumberBetData> numberBetList;   // 所有号码的押注数据
        
        /// <summary>
        /// 构造函数
        /// </summary>
        public BankingData()
        {
            numberBetList = new List<NumberBetData>();
            InitializeNumbers();
        }
        
        /// <summary>
        /// 初始化号码数据 (01-49)
        /// </summary>
        private void InitializeNumbers()
        {
            for (int i = 1; i <= 49; i++)
            {
                numberBetList.Add(new NumberBetData(i));
            }
        }
        
        /// <summary>
        /// 获取指定号码的数据
        /// </summary>
        public NumberBetData GetNumberData(int number)
        {
            return numberBetList.Find(data => data.number == number);
        }
        
        /// <summary>
        /// 更新号码押注数据
        /// </summary>
        public void UpdateNumberBet(int number, float totalBet, float selfBet)
        {
            var numberData = GetNumberData(number);
            if (numberData != null)
            {
                numberData.totalBetAmount = totalBet;
                numberData.selfBetAmount = selfBet;
                numberData.UpdateReportAmount();
                
                // 重新计算所有号码的风险值（因为总押注发生了变化）
                RecalculateAllRiskValues();
            }
        }
        
        /// <summary>
        /// 重新计算所有号码的风险值
        /// </summary>
        public void RecalculateAllRiskValues()
        {
            // 遍历所有号码，重新计算风险值
            foreach (var numberData in numberBetList)
            {
                numberData.CalculateRiskValue(odds, numberBetList);
            }
        }
        
        /// <summary>
        /// 计算总体数据
        /// </summary>
        public void CalculateTotalData()
        {
            totalBetAmount = 0f;
            totalSelfBetAmount = 0f;
            totalReportAmount = 0f;
            Debug.LogWarning("========================================");
            foreach (var numberData in numberBetList)
            {
                Debug.LogWarning($"号码{numberData.number}: 总押注={numberData.totalBetAmount}, 吃码={numberData.selfBetAmount}, 上报={numberData.reportAmount}, 风险值={numberData.riskValue}");
                totalBetAmount += numberData.totalBetAmount;
                totalSelfBetAmount += numberData.selfBetAmount;
                totalReportAmount += numberData.reportAmount;
            }
        }
        
        /// <summary>
        /// 获取统计数据
        /// </summary>
        public StatisticsData GetStatisticsData()
        {
            CalculateTotalData();
            
            var stats = new StatisticsData();
            stats.UpdateStatistics(totalBetAmount, totalSelfBetAmount, totalReportAmount, odds);
            return stats;
        }
        
        /// <summary>
        /// 获取需要上报的号码列表 (风险值过高)
        /// </summary>
        public List<NumberBetData> GetHighRiskNumbers(float riskThreshold = -5000f)
        {
            return numberBetList.FindAll(data => data.riskValue < riskThreshold);
        }
        
        /// <summary>
        /// 重置所有数据
        /// </summary>
        public void ResetAllData()
        {
            foreach (var numberData in numberBetList)
            {
                numberData.totalBetAmount = 0f;
                numberData.selfBetAmount = 0f;
                numberData.reportAmount = 0f;
                numberData.riskValue = 0f;
            }
            
            totalBetAmount = 0f;
            totalSelfBetAmount = 0f;
            totalReportAmount = 0f;
        }

        /// <summary>
        /// 获取所有号码的押注数据列表
        /// </summary>
        public List<NumberBetData> GetAllNumberBetData()
        {
            return numberBetList;
        }

        /// <summary>
        /// 更新指定号码的押注数据
        /// </summary>
        /// <param name="numberId">号码ID（1-49）</param>
        /// <param name="betData">押注数据</param>
        public void UpdateNumberBetData(int numberId, NumberBetData betData)
        {
            // 验证号码ID的有效性
            if (numberId < 1 || numberId > 49)
            {
                Debug.LogError($"[BankingData] 无效的号码ID: {numberId}，有效范围是1-49");
                return;
            }
            
            // 验证输入数据的有效性
            if (betData == null)
            {
                Debug.LogError($"[BankingData] 押注数据为空，号码ID: {numberId}");
                return;
            }
            
            // 确保输入的betData的号码与numberId一致
            if (betData.number != numberId)
            {
                Debug.LogWarning($"[BankingData] 数据不匹配：参数号码ID={numberId}，数据中的号码={betData.number}，将使用参数号码ID");
                betData.number = numberId;
            }
            
            // 查找对应的号码数据
            var existingData = GetNumberData(numberId);
            if (existingData != null)
            {
                // 更新现有数据
                existingData.totalBetAmount = betData.totalBetAmount;
                existingData.selfBetAmount = betData.selfBetAmount;
                existingData.reportAmount = betData.reportAmount;
                
                // 重新计算上报数量
                existingData.UpdateReportAmount();
                
                // 重新计算所有号码的风险值（因为总押注发生了变化）
                RecalculateAllRiskValues();
                
                Debug.Log($"[BankingData] 成功更新号码{numberId}的押注数据");
            }
            else
            {
                Debug.LogError($"[BankingData] 未找到号码{numberId}的数据");
            }
        }
    }
} 